#include "Modbus_Up.h"
static struct shm_param para;
void *hander(void *arg)
{
    modbus_t *ctx_t = ((modbus_t *)arg);
    uint16_t buf1[32] = {0};
    uint8_t buf2;
    int addr_data = 0;
    while (1)
    {
        if (msg_queue_recv("modbus_msg", &recv_buf, sizeof(recv_buf), 0, 0) > 0)
        {
            //printf("recv from msg type = %ld\n", recv_buf.mtype);
            //printf("recv from msg data = %s\n", recv_buf.mdata);
            // long size = fileopt_getsize("data.json");
            // char *json_string = (char *)malloc(size);
            // fileopt_readall("data.json", json_string);

            cJSON *cjson = cJSON_Parse(recv_buf.mdata);                //将JSON字符串转换成JSON结构体
            cJSON *mydata = cJSON_GetObjectItem(cjson, "data");     //解析对象
            int key = cJSON_GetObjectItem(mydata, "key")->valueint; //解析对象中key
            printf("%s %d\n", __func__, __LINE__);
            //printf("%d\n", key);

            struct list_head *pos;
            struct mb_node_list *tmp;
            list_for_each(pos, &head)
            {
                tmp = list_entry(pos, struct mb_node_list, list);
                if (tmp->node.key == key)
                {
                    addr_data = tmp->node.addr; //取出设备地址
                }
            }
            //printf("addr=%d\n", addr_data);
            if (key == 103)
            {
                int val = atoi(cJSON_GetObjectItem(mydata, "val")->valuestring); //解析对象中的整型数字
                //printf("val=%d\n", val);
                buf2 = val;
                modbus_write_bit(ctx_t, addr_data-1, buf2);
            }
            else if (key == 104)
            {
                double val = atof(cJSON_GetObjectItem(mydata, "val")->valuestring); //解析对象中的浮点型数字
                //printf("val=%f\n", val);
                modbus_set_float_dcba(val, buf1);
                modbus_write_registers(ctx_t, addr_data-40001, 2, buf1);
            }
            else if (key == 105)
            {
                int val = atoi(cJSON_GetObjectItem(mydata, "val")->valuestring); //解析对象中的整型数字
                //printf("val=%d\n", val);
                buf2 = val;
                modbus_write_bit(ctx_t, addr_data-1, buf2);
            }
        }
        else
        {
            perror("recv error:");
            exit(-1);
        }
    }
}

int modbus_init()
{
    int ret = -1;
    INIT_LIST_HEAD(&head);
    uint16_t buf1[32] = {0};
    uint8_t buf2[32] = {0};
    long size = fileopt_getsize("node.json");
    char *json_string = (char *)malloc(size);
    fileopt_readall("node.json", json_string);

    cJSON *cjson = cJSON_Parse(json_string); //将JSON字符串转换成JSON结构体
    if (cjson == NULL)                       //判断转换是否成功
    {
        printf("cjson error...\r\n");
    }
    else
    {
        //printf("/*********************以下是JSON结构体**********************/\n");
        //printf("%s\n", cJSON_Print(cjson)); //打包成功调用cJSON_Print打印输出
    }
    int i = 0;
    cJSON *modbus = cJSON_GetObjectItem(cjson, "modbus"); //解析对象
    cJSON *data = cJSON_GetObjectItem(modbus, "data");    //解析数组
    int data_size = cJSON_GetArraySize(data);             //获取数组成员个数
    cJSON *data_item = data->child;                       //获取子对象
    for (i = 0; i < data_size; i++)
    {
        new = (struct mb_node_list *)malloc(sizeof(struct mb_node_list));
        new->node.key = cJSON_GetObjectItem(data_item, "key")->valueint;             //解析数组中对象中的整型数字
        strcpy(new->node.name, cJSON_GetObjectItem(data_item, "name")->valuestring); //解析数组中对象中的字符串
        new->node.addr = cJSON_GetObjectItem(data_item, "addr")->valueint;           //解析数组中对象中的整型数字
        //printf("addr=%d\n", new->node.addr);
        new->node.type = cJSON_GetObjectItem(data_item, "type")->valueint; //解析数组中对象中的整型数字
        list_add(&new->list, &head);
        data_item = data_item->next; //跳转到下一个对象中
    }

    //创建共享内存
    ret = shm_init(&para, "modbus_shm", 1024);
    if (ret < 0)
    {
        return -1;
    }
    struct modbus_data *addr = shm_getaddr(&para);
    if (addr == NULL)
    {
        return -1;
    }
    //创建链接创建modbus实例
    modbus_t *ctx = modbus_new_tcp(ADDR, atoi(PORT));
    if (ctx == NULL)
    {
        errDbug;
        return -1;
    }
    //设置从机ID
    if (modbus_set_slave(ctx, 1) < 0)
    {
        errDbug;
        return -1;
    }
    //与从机相连
    modbus_connect(ctx);
    //创建数据采集线程
    pthread_t tid;
    if (pthread_create(&tid, NULL, hander, (void *)ctx) != 0)
    {
        printf("create err\n");
        return -1;
    }
    while (1)
    {
        /*开关状态模拟*/
        modbus_read_bits(ctx, 0, 2, buf2);
        int air_switch = buf2[0]; //数据转换
        int light = buf2[1];      //数据转换
        // printf("air_switch = %d\n", air_switch);
        // printf("light = %d\n", light);
        addr->air_switch = air_switch;
        addr->light = light;

        /*空调模拟*/
        modbus_read_registers(ctx, 0, 2, buf1);
        float air_temp = modbus_get_float_dcba(buf1); //数据转换
        // printf("airtemp = %0.2f\n", air_temp);
        if (addr->air_switch == 0)
        {
            addr->air_temp = 0;
        }
        else
        {
            addr->air_temp = air_temp;
        }
        memset(buf1, 0, sizeof(buf1));

        /*温湿度传感器模拟*/
        modbus_read_input_registers(ctx, 0, 4, buf1);
        float temperature = modbus_get_float_dcba(&buf1[0]); //数据转换
        float humidity = modbus_get_float_dcba(&buf1[2]);    //数据转换
        // printf("temperature = %0.2f\n", temperature);
        // printf("humidity = %0.2f\n", humidity);
        addr->temperature = temperature;
        addr->humidity = humidity;

        sleep(1);

        memset(buf1, 0, sizeof(buf1));
        memset(buf2, 0, sizeof(buf2));
    }
    pthread_join(tid, NULL); //阻塞，等待线程结束
    //释放modbus实例
    modbus_free(ctx);
    //关闭套接字
    modbus_close(ctx);
    return 0;
}